home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / gcc / ixemulsrc.lha / ixemul-41.4 / library / ix_open.c < prev    next >
C/C++ Source or Header  |  1995-05-28  |  7KB  |  213 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Portions Copyright (C) 1994 Rafael W. Luebbert
  5.  *
  6.  *  This library is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU Library General Public
  8.  *  License as published by the Free Software Foundation; either
  9.  *  version 2 of the License, or (at your option) any later version.
  10.  *
  11.  *  This library is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  *  Library General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU Library General Public
  17.  *  License along with this library; if not, write to the Free
  18.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  *  $Id: ix_open.c,v 1.7 1994/06/19 15:13:03 rluebbert Exp $
  21.  *
  22.  *  $Log: ix_open.c,v $
  23.  *  Revision 1.7  1994/06/19  15:13:03  rluebbert
  24.  *  *** empty log message ***
  25.  *
  26.  *  Revision 1.5  1992/10/20  16:20:56  mwild
  27.  *  initialize malloc-region pointer (necessary after vfork-change)
  28.  *
  29.  *  Revision 1.4  1992/08/09  20:53:36  amiga
  30.  *  clean up
  31.  *
  32.  *  Revision 1.3  1992/05/20  01:31:30  mwild
  33.  *  move atexit(_cleanup) into ix_get_vars2 after stdio initialisation
  34.  *
  35.  * Revision 1.2  1992/05/18  12:20:27  mwild
  36.  * change async mp to be global
  37.  *
  38.  * Revision 1.1  1992/05/14  19:55:40  mwild
  39.  * Initial revision
  40.  *
  41.  */
  42.  
  43. #define KERNEL
  44. #include "ixemul.h"
  45. #include "kprintf.h"
  46.  
  47. #undef u
  48. #include <hardware/intbits.h>
  49.  
  50. #include <exec/memory.h>
  51. #define BASE_EXT_DECL
  52. #define BASE_EXT_DECL0
  53. #define BASE_PAR_DECL    struct ixemul_base *ixbase,
  54. #define BASE_PAR_DECL0    struct ixemul_base *ixbase
  55. #define BASE_NAME    ixbase->ix_intui_base
  56. #include <inline/intuition.h>
  57.  
  58. extern void launch_glue (), switch_glue ();
  59. extern void trap_20 ();
  60. extern void trap_00 ();
  61. extern int ix_timer();
  62. extern void mp_interrupt ();
  63. extern struct ExecBase *SysBase;
  64.  
  65. struct ixemul_base *
  66. ix_open (struct ixemul_base *ixbase)
  67. {
  68.   /* here we must initialize our `user' structure */
  69.   struct user *u;
  70.   /* an errno for those that later don't set it in ix_startup() */
  71.   static int default_errno;
  72.   struct Task *me;
  73.   me = SysBase->ThisTask;
  74.  
  75.   u = (struct user *) kmalloc (sizeof (struct user));
  76.   if (u)  
  77.     {
  78.       curproc = u;
  79.  
  80.       /* bzero is safe, ie. doesn't need to reference struct user */
  81.       bzero (u, sizeof (struct user));
  82.  
  83.       /* remember old state */
  84.       u->u_otask_flags = me->tc_Flags;
  85.       u->u_olaunch     = me->tc_Launch;
  86.       u->u_oswitch     = me->tc_Switch;
  87.       u->u_otrap_code  = me->tc_TrapCode;
  88.       u->u_otrap_data  = me->tc_TrapData;
  89.     
  90.       NewList ((struct List *) & u->u_md.md_list);
  91.  
  92.       u->u_mdp           = & u->u_md;
  93.  
  94.       KPRINTF (("ix_open: curproc = $%lx, ix_open @$lx\n", curproc, ix_open));
  95.  
  96.       me->tc_TrapData  = (APTR) u;
  97.  
  98. if (betterthan68000())
  99.     me->tc_TrapCode  = trap_20;
  100. else
  101.     me->tc_TrapCode  = trap_00;
  102.  
  103.  
  104.       /* setup the p_sigignore mask correctly */
  105.       siginit (u);
  106.       me->tc_SigRecvd &= 0x0fff;
  107.  
  108.       /* this library is a replacement for any c-library, thus we should be
  109.        * started at the START of a program, and out of 16 available signals 
  110.        * this calls has to simply succeed... I know I'm a lazy guy ;-) */
  111.       u->u_sleep_sig   = AllocSignal (-1);
  112.  
  113.       /* network related functions are only enabled if InetBase is != 0 */
  114.       u->u_InetBase = OpenLibrary ("inet.library", 5);
  115.       if (u->u_InetBase)
  116.     {
  117.           u->u_sigurg      = AllocSignal (-1);
  118.           u->u_sigio       = AllocSignal (-1);
  119.         }
  120.  
  121.       me->tc_Launch    = launch_glue;
  122.       me->tc_Switch    = switch_glue;
  123.       me->tc_Flags    |= TF_LAUNCH | TF_SWITCH;
  124.       u->u_itimerint.is_Node.ln_Type = NT_INTERRUPT;
  125.       u->u_itimerint.is_Node.ln_Name = me->tc_Node.ln_Name;
  126.       u->u_itimerint.is_Node.ln_Pri  = 1;
  127.       u->u_itimerint.is_Data         = (APTR) me;
  128.       u->u_itimerint.is_Code         = (APTR) ix_timer;
  129.  
  130.  
  131.       AddIntServer (INTB_VERTB, & u->u_itimerint);
  132.  
  133.       u->u_trace_flags = 1;
  134.       u->u_ixbase = ixbase;
  135.       u->u_errno = &default_errno;
  136.       u->u_sync_mp = (struct MsgPort *) syscall (SYS_CreatePort, 0, 0);
  137.       
  138.       /* the CD storage. since 0 is a valid value for a lock, we use -1 */
  139.       u->u_startup_cd = (BPTR)-1;
  140.  
  141.       /* support for subprocesses ala Unix */
  142.  
  143.       /* each process starts out to be in its own process group. vfork()
  144.        * scribbles over this to inherit the parents process group instead */
  145.       u->p_pgrp = (int) me;
  146.       u->p_pptr = (struct Process *) 1;        /* hi init ;-)) */
  147.       u->p_cptr =
  148.         u->p_osptr =
  149.           u->p_ysptr = 0;            /* no children to start with */
  150.       u->p_vfork_msg = 0;
  151.       u->p_zombie_sig = AllocSignal (-1);
  152.       NewList ((struct List *) &u->p_zombies);
  153.  
  154.       if (/* u->u_async_mp && */ u->u_sync_mp)
  155.         {
  156.           u->u_time_req = (struct timerequest *)
  157.         syscall (SYS_CreateExtIO, u->u_sync_mp, sizeof (struct timerequest));
  158.       
  159.       if (u->u_time_req)
  160.         {
  161.           if (!OpenDevice (TIMERNAME, UNIT_MICROHZ,
  162.                          (struct IORequest *) u->u_time_req, 0))
  163.             {
  164.           syscall (SYS_gettimeofday, &u->u_start, 0);
  165.  
  166.           /* have to mask out ALL signals until ix_startup has had a
  167.            * chance to setup its exit jmp_buf. If not, _longjmp will
  168.            * generate a longjmp-botch using a not initialized jmpbuf! */
  169.           syscall (SYS_sigsetmask, ~0);
  170.  
  171.           /* if enabled, set the red zone pointer for stack watch */
  172.           if (ixbase->ix_red_zone_size)
  173.             {
  174.               struct Process *mep = (struct Process *) me;
  175.               struct CommandLineInterface *CLI = BTOCPTR (mep->pr_CLI);
  176.               u_int stack_size = CLI ? CLI->cli_DefaultStack * 4 : mep->pr_StackSize;
  177.  
  178.               /* I guess the above approach to find the correct stack
  179.                  size will work most of the time. But using tc_Lower
  180.                  as lower bound would probably not work. Thus I'm using
  181.                  the current stack value, not the unknown `real' top stack
  182.              as top and subtract the stack_size to get to the bottom */
  183.  
  184.               if (stack_size > ixbase->ix_red_zone_size)
  185.                 u->u_red_zone = (void *)(get_sp () - stack_size 
  186.                              + ixbase->ix_red_zone_size);
  187.             }
  188.           return ixbase;
  189.         }
  190.           /* couldn't open the timer device */
  191.           syscall (SYS_DeleteExtIO, u->u_time_req);
  192.         }
  193.         }
  194.  
  195.       if (u->u_sync_mp)
  196.         syscall (SYS_DeletePort, u->u_sync_mp);
  197.  
  198.       RemIntServer (INTB_VERTB, & u->u_itimerint);
  199.       me->tc_Flags    = u->u_otask_flags;
  200.       me->tc_Launch   = u->u_olaunch;
  201.       FreeSignal (u->u_sleep_sig);
  202.  
  203.       /* all_free() MUST come before we remove the pointer to u */
  204.       all_free ();
  205.       me->tc_TrapCode = u->u_otrap_code;
  206.       me->tc_TrapData = u->u_otrap_data;
  207.  
  208.       kfree (u);
  209.     }
  210.  
  211.   return 0;
  212. }
  213.